package com.todo.sight.infrastructure.repository.impl;

import com.alibaba.fastjson.JSONObject;
import com.todo.common.common.entity.response.page.PageResult;
import com.todo.common.common.enums.BizErrorCodeEnum;
import com.todo.common.common.exception.BizException;
import com.todo.common.utils.MathUtils;
import com.todo.sight.infrastructure.convert.SightConvert;
import com.todo.sight.infrastructure.mapper.SightBaseMapper;
import com.todo.sight.infrastructure.mapper.SightDetailMapper;
import com.todo.sight.infrastructure.repository.SightInfoRepository;
import com.todo.sight.infrastructure.entity.condition.SightBaseCondition;

import com.todo.sight.infrastructure.entity.domain.SightInfoDO;
import com.todo.sight.infrastructure.entity.po.SightBasePO;
import com.todo.sight.infrastructure.entity.po.SightDetailPO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;

/**
 * (SightBase)表服务实现类
 *
 * @author zhangwenxiang
 * @since 2024-03-04 21:10:04
 */
@Slf4j
@Repository("sightBaseRepository")
public class SightInfoRepositoryImpl implements SightInfoRepository {
    @Resource
    private SightBaseMapper sightBaseMapper;
    @Resource
    private SightDetailMapper sightDetailMapper;


    @Override
    @Transactional
    public Boolean insertSightInfoDetail(SightInfoDO sightInfoDO) {
        if (sightInfoDO == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        if (!baseFieldCheck(sightInfoDO) || sightInfoDO.getSightBase().getPoiId() == null) {
            return false;
        }
        SightBasePO sightBasePO = SightConvert.builderSightBasePO(sightInfoDO);
        int baseResult = sightBaseMapper.insertSightBasePO(sightBasePO);
        if (baseResult == 0) {
            log.warn("SightInfoRepository#insertSightInfoDetail 新增景点信息失败，基础信息保存失败，默认操作失败 sightBasePO：【{}】", JSONObject.toJSONString(sightBasePO));
            return false;
        }
        SightDetailPO sightDetailPO = SightConvert.builderSightDetailPO(sightInfoDO);
        int detailResult = sightDetailMapper.insertSightDetailPO(sightDetailPO);
        if (detailResult == 0) {
            log.warn("SightInfoRepository#insertSightInfoDetail 新增景点信息失败，详情信息保存失败，默认操作失败 sightDetailPO：【{}】", JSONObject.toJSONString(sightDetailPO));
            throw new BizException(BizErrorCodeEnum.SYSTEM_ERROR);
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean updateSightInfoDetailById(SightInfoDO sightInfoDO) {
        if (sightInfoDO == null) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        if (!baseFieldCheck(sightInfoDO)) {
            return false;
        }
        SightBasePO sightBasePO = SightConvert.builderSightBasePO(sightInfoDO);
        int baseResult = sightBaseMapper.updateSightBasePOById(sightBasePO);
        if (baseResult == 0) {
            log.warn("SightInfoRepository#updateSightInfoDetailById 更新景点信息失败，详情信息保存失败，默认操作失败 sightBasePO：【{}】", JSONObject.toJSONString(sightBasePO));
            return false;
        }
        SightDetailPO sightDetailPO = SightConvert.builderSightDetailPO(sightInfoDO);
        int detailResult = sightDetailMapper.updateSightDetailPOById(sightDetailPO);
        if (detailResult == 0) {
            log.warn("SightInfoRepository#updateSightInfoDetailById 更新景点信息失败，详情信息保存失败，默认操作失败 sightDetailPO：【{}】", JSONObject.toJSONString(sightDetailPO));
            throw new BizException(BizErrorCodeEnum.SYSTEM_ERROR);
        }
        return true;
    }


    @Override
    public SightInfoDO querySightInfoDetailById(Long id) {
        if (id == null || id < 0) {
            return null;
        }
        SightBasePO sightBasePO = sightBaseMapper.querySightBasePOById(id);
        if (sightBasePO == null) {
            log.warn("SightInfoRepository#querySightInfoDetailById 根据主键查询景点信息失败，基础信息为空 id：【{}】", id);
            return null;
        }
        SightDetailPO sightDetailPO = sightDetailMapper.querySightDetailPOById(id);
        if (sightDetailPO == null) {
            log.warn("SightInfoRepository#querySightInfoDetailById 根据主键查询景点信息失败，详情信息为空 sightBasePO：【{}】", JSONObject.toJSONString(sightBasePO));
            return null;
        }
        SightInfoDO sightInfoDO = SightConvert.convertToSightInfoDO(sightBasePO, sightDetailPO);
        return sightInfoDO;
    }

    @Override
    public SightBasePO querySightBasePOById(Long id) {
        if (id == null || id < 0) {
            return null;
        }
        SightBasePO sightBasePO = sightBaseMapper.querySightBasePOById(id);
        return sightBasePO;
    }

    @Override
    public SightInfoDO querySightInfoDetailByPOI(Long poiId) {
        if (poiId == null || poiId < 0) {
            return null;
        }
        SightBasePO sightBasePO = sightBaseMapper.querySightBasePOByPOI(poiId);
        if (sightBasePO == null) {
            return null;
        }
        return querySightInfoDetailById(sightBasePO.getId());
    }

    @Override
    @Transactional
    public Boolean removeSightBasePOById(Long id) {
        if (id == null || id < 0) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        SightBasePO sightBasePO = querySightBasePOById(id);
        if (sightBasePO == null) {
            log.warn("SightInfoRepository#removeSightBasePOById 根据主键查询景点信息失败，详情信息为空 id：【{}】", id);
            return true;
        }
        int baseRemove = sightBaseMapper.removeSightBasePOById(id);
        if (baseRemove == 0) {
            log.warn("SightInfoRepository#removeSightBasePOById 删除基础数据失败，默认操作失败 id：【{}】", id);
            return false;
        }
        int detailRemove = sightDetailMapper.removeSightDetailPOById(id);
        if (detailRemove == 0) {
            log.warn("SightInfoRepository#removeSightBasePOById 删除详情数据失败，默认异常回滚 id：【{}】", id);
            throw new BizException(BizErrorCodeEnum.SYSTEM_ERROR);
        }
        return true;
    }

    @Override
    @Transactional
    public Boolean removeSightByPOI(Long poiId) {
        if (poiId == null || poiId < 0) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        SightBasePO sightBasePO = sightBaseMapper.querySightBasePOByPOI(poiId);
        if (sightBasePO == null) {
            return null;
        }
        return removeSightBasePOById(sightBasePO.getId());
    }

    @Override
    public PageResult<SightBasePO> querySightBaseByCondition(SightBaseCondition sightBaseCondition) {
        PageResult<SightBasePO> pageResult = new PageResult<>();
        if (sightBaseCondition == null) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        pageResult.setPageNum(sightBaseCondition.getPageIndex());
        pageResult.setPageSize(sightBaseCondition.getPageSize());
        long count = queryCountByCondition(sightBaseCondition);
        if (count <= 0) {
            return pageResult;
        }
        pageResult.setPageCount((int) MathUtils.divide(count, sightBaseCondition.getPageSize()));
        pageResult.setTotal(count);
        List<SightBasePO> sightPoiPOList = sightBaseMapper.querySightBaseByCondition(sightBaseCondition);
        if (CollectionUtils.isEmpty(sightPoiPOList)) {
            pageResult.setHasNext(false);
            return pageResult;
        }
        pageResult.setResults(sightPoiPOList);
        pageResult.setCurrentIndex(sightPoiPOList.get(0).getId());
        pageResult.setHasNext(sightPoiPOList.size() >= sightBaseCondition.getPageSize());
        return pageResult;
    }

    @Override
    public Long queryCountByCondition(SightBaseCondition sightBaseCondition) {
        if (sightBaseCondition == null || sightBaseCondition.getPageSize() <= 0) {
            throw new BizException(BizErrorCodeEnum.DATA_NOT_EXIST);
        }
        return sightBaseMapper.queryCountByCondition(sightBaseCondition);
    }

    @Override
    public Boolean showSightBasePOById(Long id, Integer show) {
        if (id == null || id < 0) {
            throw new BizException(BizErrorCodeEnum.PARAM_ERROR);
        }
        SightBasePO sightBasePO = new SightBasePO();
        sightBasePO.setId(id);
        sightBasePO.setIsShow(show);
        return sightBaseMapper.updateSightBasePOById(sightBasePO) > 0;
    }

    @Override
    public List<SightBasePO> querySightInfoByPoiIdList(List<Long> poiIdList) {
        if (CollectionUtils.isEmpty(poiIdList)) {
            return Collections.emptyList();
        }
        return sightBaseMapper.querySightInfoByPoiIdList(poiIdList);
    }


    private boolean baseFieldCheck(SightInfoDO sightInfoDO) {
        if (sightInfoDO == null) {
            return false;
        }
        if (sightInfoDO.getSightBase() == null || sightInfoDO.getSightDetail() == null) {
            log.warn("SightInfoRepository#baseFieldCheck 核心数据校验失败，操作操作失败 sightInfoDO：【{}】", JSONObject.toJSONString(sightInfoDO));
            return false;
        }
        SightInfoDO.SightBase sightBase = sightInfoDO.getSightBase();
        if (sightBase.getTitle() == null || sightBase.getSlogan() == null ||  sightBase.getSource() == null) {
            log.warn("SightInfoRepository#baseFieldCheck 基础数据校验失败，操作操作失败 sightInfoDO：【{}】", JSONObject.toJSONString(sightInfoDO));
            return false;
        }
        SightInfoDO.SightDetail sightDetail = sightInfoDO.getSightDetail();
        if (sightDetail.getDesc() == null) {
            log.warn("SightInfoRepository#baseFieldCheck 详情数据校验失败，操作操作失败 sightInfoDO：【{}】", JSONObject.toJSONString(sightInfoDO));
            return false;
        }
        return true;
    }
}
